{
  LW Light -- LightWave Lighting

  Light handlers implement different types of light.
  Before LightWave® 9.5 only a fixed set of built-in light types were available.
  With version 9.5 the light calculations have been moved to a plugin API,
  enabling an unlimited range of light types to be added.

  Based on lwlight.h which is:
  Copyright 2007, NewTek, Inc.
}

{
  Copyright 2012, Jameel Halabi

  This unit is part of the BlaiseWave wrapper,
  which is licensed under the BSD 2-Clause license (see licenses/license.txt).
}

unit LW_Light;

{$mode objfpc}{$H+}

interface

uses
  LW_Types   ,
  LW_Handler ,
  LW_Render  ;

const
  LWLIGHT_HCLASS   = 'LightHandler'   ;
  LWLIGHT_ICLASS   = 'LightInterface' ;
  LWLIGHT_GCLASS   = 'LightGizmo'     ;
  LWLIGHT_VERSION  = 2                ;

  // Light access flags
  LWLF_SAMPLEDRAY  = 1 shl 0 ;
  LWLF_HAVESURFACE = 1 shl 1 ;
  LWLF_PREPROCESS  = 1 shl 2 ;

  // Preview light types
  LWPREVIEWLIGHT_DISTANT = 0  ;
  LWPREVIEWLIGHT_POINT   = 1  ;
  LWPREVIEWLIGHT_SPOT    = 2  ;
  LWPREVIEWLIGHT_AMBIENT = 3  ;

  LWPREVIEWLIGHT_END     = -1 ;

  // Light handler flags
  LWLIGHTTYPEF_NO_PHOTONS           = 1 shl 0 ;    // Photon generation not supported (e.g. caustics)
  LWLIGHTTYPEF_NO_RAYILLUM          = 1 shl 1 ;    // Ray illumination not supported (e.g. volumetric lights)
  LWLIGHTTYPEF_OCCLUSION_SHADOWED   = 1 shl 2 ;    // Returned illumination includes occlusion shadow effects
  LWLIGHTTYPEF_VOLUMETRICS_SHADOWED = 1 shl 3 ;    // Returned illumination includes volumetric shadow effects

  LWLIGHTTYPEF_NO_FALLOFF           = 1 shl 4 ;    // Do not show standard falloff gadgets, and do not apply
  LWLIGHTTYPEF_SHOW_FALLOFF         = 1 shl 5 ;    // Show the standard falloff gadgets, but do not apply

  LWLIGHTEVALUATIONFUNCS_GLOBAL = 'LW Light Evaluation Funcs' ;

type
  PLWLightAccess = ^TLWLightAccess;
  TLWLightAccess = record
    LightID                   : PLWItem                   ;

    WorldPos                  : TLWDVector                ;

    ToWorld                   : array[0..2] of TLWDVector ;
    ToLight                   : array[0..2] of TLWDVector ;

    MaxIlluminations          : UInt32                    ;

    RayCast                   : TLWRayCastFunc            ;
    RandomData                : PRandomFloatData          ;
    RandomFloat               : TLWRandomFloatFunc        ;

    Bounces                   : UInt32                    ;
    Flags                     : UInt32                    ;

    SurfaceNormal             : TLWDVector                ;

    SamplerState              : PLWSamplerState           ;
    GetSamplerRange           : TLWGetSamplerRangeFunc    ;
    GetSample2D               : TLWGetSample2DFunc        ;
    GetSample1D               : TLWGetSample1DFunc        ;
  end;

  { Light plugins can return an array of standard lights
    to create a preview. The array is terminated with a
    preview light type of LWPREVIEWLIGHT_END.           }
  PLWPreviewLight = ^TLWPreviewLight ;
  TLWPreviewLight = record
    Previewtype   : Integer                   ;  // One of the LWPREVIEWLIGHT_ values below
    WorldPos      : array[0..2] of TLWDVector ;  // The light to world transformation matrix
    ToWorld       : array[0..2] of TLWDVector ;

    Color         : TLWDVector                ;  // Color and intensity of the light
    Intensity     ,

    Range         : Double                    ;  // Falloff
    Falloff       : Integer                   ;

    ConeAngle     ,                              // Cone for spot lights
    ConeEdge      : Double                    ;
  end;

  // Light evaluation fills in an array of illuminations
  PLWIllumination = ^TLWIllumination ;
  TLWIllumination = record
    Color             : TLWDVector ;  // Color, not including intensity or shadow effects

    Intensity         : Double     ;  // Intensity, not including shadow effects
    Direction         : TLWDVector ;  // Direction in which the illumination is going, normalized
    Distance          : Double     ;  // Distance to origin of illumination along ray; DBL_MAX if infinite
    ShadowAttenuation : TLWDVector ;  // Degree of shadowing to apply
  end;


  // Description of a photon shot from a light
  PLWPhoton = ^TLWPhoton ;
  TLWPhoton = record
    Color             : TLWDVector ;
    Intensity         : Double     ;
    Direction         ,
    WorldPos          : TLWDVector ;
  end;

  PLWRayIllumination = ^TLWRayIllumination ;
  TLWRayIllumination = record
    Color             : TLWDVector ;
    Intensity         : Double     ;
    Distance          : TLWDVector ;
  end;

  PLWLightHandler = ^TLWLightHandler ;
  TLWLightHandler = record
    Inst        : PLWInstanceFuncs;
    Item        : PLWItemFuncs    ;
    Rend        : PLWRenderFuncs  ;
    Flags       : function
                  (       Instance : PLWInstance   ) : UInt32;
    NewFrame    : function
                  (       Instance         : PLWInstance    ;
                    const FrameInfo        : PLWFrameInfo   ;
                          MaxIlluminations : PUInt32        ;
                          LightAccess      : PLWLightAccess ) : PLWError ;
    Evaluate    : function
                  (       Instance         : PLWInstance              ;
                          Spot             : TLWDVector               ;
                          FracTime         : Double                   ;
                          Illumination     : array of TLWIllumination ;
                    const LightAccess      : PLWLightAccess           ) : Integer ;
    GetPhotons  : function
                  (       Instance    : PLWInstance        ;
                          MaxPhotons  : UInt32             ;
                          Photons     : array of TLWPhoton ;
                    const LightAccess : PLWLightAccess     ) : UInt32;
    GetRayIlluminations : function
                          (       Instance            : PLWInstance                 ;
                                  RayStart            : TLWDVector                  ;
                                  RayDir              : TLWDVector                  ;
                                  FarClip             : Double                      ;
                                  MaxRayIlluminations : UInt32                      ;
                                  RayIlluminations    : array of TLWRayIllumination ;
                            const LightAccess         : PLWLightAccess              ) : UInt32;
    Preview     : function
                  (       Instance : PLWInstance   ) : PLWPreviewLight;  // const
  end;

  PLWLightEvaluator = Pointer ;

  PLWLightEvaluationFuncs = ^TLWLightEvaluationFuncs ;
  TLWLightEvaluationFuncs = record
    Create     : function
                 (       LightID           : PLWItem             ) : PLWLightEvaluator ;
    Destroy    : procedure
                 (       LightEvaluatorID  : PLWLightEvaluator   ) ;
    Flags      : function
                 (       LightEvaluatorID  : PLWLightEvaluator   ) : UInt32  ;
    Init       : function
                 (       LightEvaluatorID  : PLWLightEvaluator   ;
                         Mode              : Integer             ) : PLWError  ;
    CleanUp    : procedure
                 (       LightEvaluatorID  : PLWLightEvaluator   ) ;
    NewTime    : function
                 (       LightEvaluatorID  : PLWLightEvaluator   ;
                         Frame             : TLWFrame            ;
                         InTime            : TLWTime             ) : PLWError  ;
    NewFrame   : function
                 (       LightEvaluatorID  : PLWLightEvaluator   ;
                   const FrameInfo         : PLWFrameInfo        ;
                         MaxIlluminations  : PUInt32             ;
                   const LightAccess       : PLWLightAccess      ) : PLWError  ;
    Evaluate   : function
                 (       LightEvaluatorID  : PLWLightEvaluator       ;
                         Spot             : TLWDVector               ;
                         FracTime         : Double                   ;
                         Illumination     : array of TLWIllumination ;
                   const LightAccess      : PLWLightAccess           ) : Integer ;
    GetPhotons : function
                 (       LightEvaluatorID  : PLWLightEvaluator  ;
                         MaxPhotons        : UInt32             ;
                         Photons           : array of TLWPhoton ;
                   const LightAccess       : PLWLightAccess     ) : UInt32;
    GetRayIlluminations : function
                          (       LightEvaluatorID    : PLWLightEvaluator           ;
                                  RayStart            : TLWDVector                  ;
                                  RayDir              : TLWDVector                  ;
                                  FarClip             : Double                      ;
                                  MaxRayIlluminations : UInt32                      ;
                                  RayIlluminations    : array of TLWRayIllumination ;
                            const LightAccess         : PLWLightAccess              ) : UInt32;
  end;

implementation

end.

